package com.cruise.game.service.impl.game;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cruise.game.common.api.ApiException;
import com.cruise.game.common.constants.CacheConstants;
import com.cruise.game.common.utils.RedisUtils;
import com.cruise.game.common.utils.SecurityUtils;
import com.cruise.game.mapper.AgentMapper;
import com.cruise.game.mapper.GameCategoryMapper;
import com.cruise.game.mapper.GameServiceMapper;
import com.cruise.game.mapper.UserMapper;
import com.cruise.game.model.entity.Agent;
import com.cruise.game.model.entity.GameCategory;
import com.cruise.game.model.entity.GameService;
import com.cruise.game.model.entity.User;
import com.cruise.game.model.param.game.GameServiceCreateParam;
import com.cruise.game.model.param.game.GameServiceQueryParam;
import com.cruise.game.model.param.game.GameServiceUpdateParam;
import com.cruise.game.model.vo.common.PageResult;
import com.cruise.game.model.vo.game.GameServiceListVO;
import com.cruise.game.model.vo.game.GameServiceVO;
import com.cruise.game.service.common.UploadService;
import com.cruise.game.service.game.ServiceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 游戏服务服务实现
 * 
 * @author cruise
 * @date 2025-02-28
 */
@Slf4j
@Service
public class ServiceServiceImpl implements ServiceService {

    @Resource
    private GameServiceMapper gameServiceMapper;

    @Resource
    private GameCategoryMapper gameCategoryMapper;

    @Resource
    private AgentMapper agentMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private UploadService uploadService;

    @Override
    public PageResult<GameServiceListVO> getServiceList(GameServiceQueryParam param) {
        // 构建查询条件
        LambdaQueryWrapper<GameService> queryWrapper = new LambdaQueryWrapper<>();

        // 分类查询
        if (param.getCategoryId() != null) {
            queryWrapper.eq(GameService::getCategoryId, param.getCategoryId());
        }

        // 代理查询
        if (param.getAgentId() != null) {
            queryWrapper.eq(GameService::getAgentId, param.getAgentId());
        }

        // 关键词查询
        if (StringUtils.isNotBlank(param.getKeyword())) {
            queryWrapper.like(GameService::getName, param.getKeyword())
                    .or()
                    .like(GameService::getDescription, param.getKeyword());
        }

        // 价格范围查询
        if (param.getMinPrice() != null) {
            queryWrapper.ge(GameService::getPrice, param.getMinPrice());
        }
        if (param.getMaxPrice() != null) {
            queryWrapper.le(GameService::getPrice, param.getMaxPrice());
        }

        // 热门、推荐查询
        if (param.getIsHot() != null) {
            queryWrapper.eq(GameService::getIsHot, param.getIsHot() ? 1 : 0);
        }
        if (param.getIsRecommended() != null) {
            queryWrapper.eq(GameService::getIsRecommended, param.getIsRecommended() ? 1 : 0);
        }

        // 只查询活动状态的服务
        queryWrapper.eq(GameService::getStatus, "active");

        // 排序
        if (StringUtils.isNotBlank(param.getSortBy())) {
            switch (param.getSortBy()) {
                case "price":
                    if ("asc".equalsIgnoreCase(param.getSortOrder())) {
                        queryWrapper.orderByAsc(GameService::getPrice);
                    } else {
                        queryWrapper.orderByDesc(GameService::getPrice);
                    }
                    break;
                case "createdAt":
                    if ("asc".equalsIgnoreCase(param.getSortOrder())) {
                        queryWrapper.orderByAsc(GameService::getCreatedAt);
                    } else {
                        queryWrapper.orderByDesc(GameService::getCreatedAt);
                    }
                    break;
                default:
                    queryWrapper.orderByDesc(GameService::getCreatedAt);
                    break;
            }
        } else {
            queryWrapper.orderByDesc(GameService::getCreatedAt);
        }

        // 查询总数
        long total = gameServiceMapper.selectCount(queryWrapper);

        // 分页参数
        queryWrapper.last("LIMIT " + (param.getPage() - 1) * param.getPageSize() + ", " + param.getPageSize());

        // 查询数据
        List<GameService> services = gameServiceMapper.selectList(queryWrapper);

        // 转换为VO
        List<GameServiceListVO> serviceVOs = convertToServiceListVOs(services);

        // 返回分页结果
        return PageResult.of(serviceVOs, total, param.getPage(), param.getPageSize());
    }

    @Override
    public GameServiceVO getServiceDetail(Long serviceId) {
        // 查询游戏服务
        GameService gameService = gameServiceMapper.selectById(serviceId);
        if (gameService == null || !"active".equals(gameService.getStatus())) {
            throw new ApiException("游戏服务不存在或已下架");
        }

        // 构建游戏服务VO
        GameServiceVO serviceVO = new GameServiceVO();
        BeanUtils.copyProperties(gameService, serviceVO);

        // 设置是否热门、推荐
        serviceVO.setIsHot(gameService.getIsHot() == 1);
        serviceVO.setIsRecommended(gameService.getIsRecommended() == 1);

        // 设置分类信息
        GameCategory category = gameCategoryMapper.selectById(gameService.getCategoryId());
        if (category != null) {
            GameServiceVO.CategoryInfo categoryInfo = new GameServiceVO.CategoryInfo();
            categoryInfo.setId(category.getId());
            categoryInfo.setName(category.getName());
            serviceVO.setCategory(categoryInfo);
        }

        // 设置代理信息
        Agent agent = agentMapper.selectById(gameService.getAgentId());
        if (agent != null) {
            GameServiceVO.AgentInfo agentInfo = new GameServiceVO.AgentInfo();
            agentInfo.setId(agent.getId());
            agentInfo.setRating(agent.getRating());
            agentInfo.setOrdersCompleted(agent.getOrdersCompleted());

            User user = userMapper.selectById(agent.getUserId());
            if (user != null) {
                agentInfo.setNickname(user.getNickname());
            }

            serviceVO.setAgent(agentInfo);
        }

        return serviceVO;
    }

    @Override
    public PageResult<GameServiceListVO> searchServices(String keyword, Integer page, Integer pageSize) {
        if (StringUtils.isBlank(keyword)) {
            return PageResult.empty();
        }

        // 构建查询条件
        LambdaQueryWrapper<GameService> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(GameService::getName, keyword)
                .or()
                .like(GameService::getDescription, keyword);
        queryWrapper.eq(GameService::getStatus, "active");
        queryWrapper.orderByDesc(GameService::getCreatedAt);

        // 查询总数
        long total = gameServiceMapper.selectCount(queryWrapper);

        // 分页参数
        queryWrapper.last("LIMIT " + (page - 1) * pageSize + ", " + pageSize);

        // 查询数据
        List<GameService> services = gameServiceMapper.selectList(queryWrapper);

        // 转换为VO
        List<GameServiceListVO> serviceVOs = convertToServiceListVOs(services);

        // 返回分页结果
        return PageResult.of(serviceVOs, total, page, pageSize);
    }

    @Override
    public List<GameServiceListVO> getHotServiceList(Integer limit) {
        // 从缓存中获取
        @SuppressWarnings("unchecked")
        List<GameServiceListVO> cachedList = (List<GameServiceListVO>) redisUtils
                .get(CacheConstants.HOT_GAME_SERVICE_LIST_CACHE);
        if (cachedList != null) {
            return cachedList;
        }

        // 查询热门游戏服务
        List<GameService> hotServices = gameServiceMapper.selectHotList(limit);

        // 转换为VO
        List<GameServiceListVO> serviceVOs = convertToServiceListVOs(hotServices);

        // 缓存结果
        redisUtils.set(CacheConstants.HOT_GAME_SERVICE_LIST_CACHE, serviceVOs,
                CacheConstants.GAME_SERVICE_CACHE_EXPIRE);

        return serviceVOs;
    }

    @Override
    public List<GameServiceListVO> getRecommendedServiceList(Integer limit) {
        // 从缓存中获取
        @SuppressWarnings("unchecked")
        List<GameServiceListVO> cachedList = (List<GameServiceListVO>) redisUtils
                .get(CacheConstants.RECOMMENDED_GAME_SERVICE_LIST_CACHE);
        if (cachedList != null) {
            return cachedList;
        }

        // 查询推荐游戏服务
        List<GameService> recommendedServices = gameServiceMapper.selectRecommendedList(limit);

        // 转换为VO
        List<GameServiceListVO> serviceVOs = convertToServiceListVOs(recommendedServices);

        // 缓存结果
        redisUtils.set(CacheConstants.RECOMMENDED_GAME_SERVICE_LIST_CACHE, serviceVOs,
                CacheConstants.GAME_SERVICE_CACHE_EXPIRE);

        return serviceVOs;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createService(GameServiceCreateParam param, Long agentId) {
        // 验证代理是否存在
        Agent agent = agentMapper.selectById(agentId);
        if (agent == null) {
            throw new ApiException("代理不存在");
        }

        // 验证分类是否存在
        GameCategory category = gameCategoryMapper.selectById(param.getCategoryId());
        if (category == null || !"active".equals(category.getStatus())) {
            throw new ApiException("游戏分类不存在或已禁用");
        }

        // 构建游戏服务对象
        GameService gameService = new GameService();
        BeanUtils.copyProperties(param, gameService);

        // 设置代理ID
        gameService.setAgentId(agentId);

        // 设置是否热门、推荐
        gameService.setIsHot(param.getIsHot() != null && param.getIsHot() ? 1 : 0);
        gameService.setIsRecommended(param.getIsRecommended() != null && param.getIsRecommended() ? 1 : 0);

        // 设置状态和时间
        gameService.setStatus("active");
        LocalDateTime now = LocalDateTime.now();
        gameService.setCreatedAt(now);
        gameService.setUpdatedAt(now);

        // 保存游戏服务
        gameServiceMapper.insert(gameService);

        // 清除缓存
        clearServiceCache();

        return gameService.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateService(Long serviceId, GameServiceUpdateParam param, Long agentId) {
        // 查询游戏服务
        GameService gameService = gameServiceMapper.selectById(serviceId);
        if (gameService == null) {
            throw new ApiException("游戏服务不存在");
        }

        // 获取当前用户是否为管理员
        boolean isAdmin = SecurityUtils.isAdmin();

        // 验证操作权限，如果是管理员则跳过权限检查
        if (!isAdmin && !Objects.equals(gameService.getAgentId(), agentId)) {
            throw new ApiException("无权操作此游戏服务");
        }

        // 验证分类是否存在
        if (param.getCategoryId() != null) {
            GameCategory category = gameCategoryMapper.selectById(param.getCategoryId());
            if (category == null || !"active".equals(category.getStatus())) {
                throw new ApiException("游戏分类不存在或已禁用");
            }
            gameService.setCategoryId(param.getCategoryId());
        }

        // 旧图片URL
        String oldImageUrl = gameService.getImageUrl();

        // 更新游戏服务
        if (StringUtils.isNotBlank(param.getName())) {
            gameService.setName(param.getName());
        }
        if (param.getPrice() != null) {
            gameService.setPrice(param.getPrice());
        }
        if (param.getDescription() != null) {
            gameService.setDescription(param.getDescription());
        }
        if (StringUtils.isNotBlank(param.getImageUrl())) {
            gameService.setImageUrl(param.getImageUrl());
        }
        if (param.getIsHot() != null) {
            gameService.setIsHot(param.getIsHot() ? 1 : 0);
        }
        if (param.getIsRecommended() != null) {
            gameService.setIsRecommended(param.getIsRecommended() ? 1 : 0);
        }
        if (StringUtils.isNotBlank(param.getStatus())) {
            gameService.setStatus(param.getStatus());
        }

        // 设置更新时间
        gameService.setUpdatedAt(LocalDateTime.now());

        // 更新游戏服务
        boolean success = gameServiceMapper.updateById(gameService) > 0;

        // 清除缓存
        if (success) {
            clearServiceCache();

            // 删除旧图片
            if (StringUtils.isNotBlank(oldImageUrl) && StringUtils.isNotBlank(param.getImageUrl())
                    && !oldImageUrl.equals(param.getImageUrl())) {
                try {
                    uploadService.deleteFile(oldImageUrl);
                } catch (Exception e) {
                    log.error("删除旧游戏服务图片失败: {}", e.getMessage(), e);
                }
            }
        }

        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteService(Long serviceId, Long agentId) {
        // 查询游戏服务
        GameService gameService = gameServiceMapper.selectById(serviceId);
        if (gameService == null) {
            throw new ApiException("游戏服务不存在");
        }

        // 获取当前用户是否为管理员
        boolean isAdmin = SecurityUtils.isAdmin();

        // 验证操作权限，如果是管理员则跳过权限检查
        if (!isAdmin && !Objects.equals(gameService.getAgentId(), agentId)) {
            throw new ApiException("无权操作此游戏服务");
        }

        // 服务图片URL
        String imageUrl = gameService.getImageUrl();

        // 删除游戏服务
        boolean success = gameServiceMapper.deleteById(serviceId) > 0;

        // 清除缓存
        if (success) {
            clearServiceCache();

            // 删除图片
            if (StringUtils.isNotBlank(imageUrl)) {
                try {
                    uploadService.deleteFile(imageUrl);
                } catch (Exception e) {
                    log.error("删除游戏服务图片失败: {}", e.getMessage(), e);
                }
            }
        }

        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateServiceStatus(Long serviceId, String status, Long agentId) {
        // 查询游戏服务
        GameService gameService = gameServiceMapper.selectById(serviceId);
        if (gameService == null) {
            throw new ApiException("游戏服务不存在");
        }

        // 获取当前用户是否为管理员
        boolean isAdmin = SecurityUtils.isAdmin();

        // 验证操作权限，如果是管理员则跳过权限检查
        if (!isAdmin && !Objects.equals(gameService.getAgentId(), agentId)) {
            throw new ApiException("无权操作此游戏服务");
        }

        // 更新状态
        boolean success = gameServiceMapper.updateStatus(serviceId, status) > 0;

        // 清除缓存
        if (success) {
            clearServiceCache();
        }

        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean adminUpdateServiceStatus(Long serviceId, String status) {
        // 查询游戏服务
        GameService gameService = gameServiceMapper.selectById(serviceId);
        if (gameService == null) {
            throw new ApiException("游戏服务不存在");
        }

        // 更新状态
        boolean success = gameServiceMapper.updateStatus(serviceId, status) > 0;

        // 清除缓存
        if (success) {
            clearServiceCache();
        }

        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean adminSetHotService(Long serviceId, Boolean isHot) {
        // 查询游戏服务
        GameService gameService = gameServiceMapper.selectById(serviceId);
        if (gameService == null) {
            throw new ApiException("游戏服务不存在");
        }

        // 更新是否热门
        boolean success = gameServiceMapper.updateIsHot(serviceId, isHot ? 1 : 0) > 0;

        // 清除缓存
        if (success) {
            clearServiceCache();
        }

        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean adminSetRecommendedService(Long serviceId, Boolean isRecommended) {
        // 查询游戏服务
        GameService gameService = gameServiceMapper.selectById(serviceId);
        if (gameService == null) {
            throw new ApiException("游戏服务不存在");
        }

        // 更新是否推荐
        boolean success = gameServiceMapper.updateIsRecommended(serviceId, isRecommended ? 1 : 0) > 0;

        // 清除缓存
        if (success) {
            clearServiceCache();
        }

        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean adminDeleteService(Long serviceId) {
        // 查询游戏服务
        GameService gameService = gameServiceMapper.selectById(serviceId);
        if (gameService == null) {
            throw new ApiException("游戏服务不存在");
        }

        // 服务图片URL
        String imageUrl = gameService.getImageUrl();

        // 删除游戏服务
        boolean success = gameServiceMapper.deleteById(serviceId) > 0;

        // 清除缓存
        if (success) {
            clearServiceCache();

            // 删除图片
            if (StringUtils.isNotBlank(imageUrl)) {
                try {
                    uploadService.deleteFile(imageUrl);
                } catch (Exception e) {
                    log.error("删除游戏服务图片失败: {}", e.getMessage(), e);
                }
            }
        }

        return success;
    }

    /**
     * 转换为游戏服务列表VO
     */
    private List<GameServiceListVO> convertToServiceListVOs(List<GameService> services) {
        if (services == null || services.isEmpty()) {
            return new ArrayList<>();
        }

        return services.stream().map(service -> {
            GameServiceListVO vo = new GameServiceListVO();
            BeanUtils.copyProperties(service, vo);

            // 设置是否热门、推荐
            vo.setIsHot(service.getIsHot() == 1);
            vo.setIsRecommended(service.getIsRecommended() == 1);

            // 设置代理信息
            Agent agent = agentMapper.selectById(service.getAgentId());
            if (agent != null) {
                GameServiceListVO.AgentInfo agentInfo = new GameServiceListVO.AgentInfo();
                agentInfo.setId(agent.getId());
                agentInfo.setRating(agent.getRating());

                User user = userMapper.selectById(agent.getUserId());
                if (user != null) {
                    agentInfo.setNickname(user.getNickname());
                }

                vo.setAgent(agentInfo);
            }

            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 清除游戏服务相关缓存
     */
    private void clearServiceCache() {
        redisUtils.del(CacheConstants.HOT_GAME_SERVICE_LIST_CACHE);
        redisUtils.del(CacheConstants.RECOMMENDED_GAME_SERVICE_LIST_CACHE);
        redisUtils.del(CacheConstants.HOME_DATA_CACHE);
    }
}
